package cn.zyl.common.redis.enums;

/**
 * RedisDataEnum枚举说明: redis 的数据类型
 *<pre>
 *     scan 游标 match 正则 count 条数 ：基于游标的迭代器，每次调用后，向用户返回新游标，下次迭代使用新游标作为参数， 以此延续迭代过程，当游标设置为 0 时，开始一次迭代，当服务器返回 0 的游标时，表示迭代结束
 *
 *     multi ：开启事务命令，之后的命令就进入队列，而不会马上被执行
 *     watch k1 k2... :监听某些键，当被监听的键在事务执行前被修改，则事务会被回滚
 *     unwatch k1 k2... :取消监听某些键
 *     exec :执行事务，如果被监听的键没有被修改，则采用执行命令，否则就回滚命令
 *     discard :回滚事务
 *
 *     persist k :持久化k,取消超时时间
 *     ttl k :查看k的超时时间，-1代表没有超时时间
 *     expire k s :k设置超时时间戳s(秒）
 *     expire.at k t :k设置超时时间点（uninx时间戳）
 *     p.ptl k m :查看key的超时时间戳(毫秒）
 *     p.expire k :设置键值超时的时间(毫秒）
 *     p.expire.at k s :设置超时时间点（uninx时间戳）
 *
 *     eval lua-script kn k1 k2... v1 v2... :执行lua命令脚本，kn参数个数，多个参数k，多个值v
 *     script load s :缓存lua脚本s,返回脚本sha-1字符串
 *     eval.sha sha-1 kn k1 k2... p1 p2... :根据sha-1执行脚本，kn参数个数，多个参数k，多个参数p
 *
 *     subscribe q :订阅模式-注册消息渠道q
 *     publish q v :订阅模式-将消息v发送到渠道q
 *</pre>
 * @author wsz
 * @version v1.0
 * @date 2020-08-06
 */
public enum RedisDataEnum {
    /** 基本数据类型：字符串，二进制安全，可包括序列化对象，最大能存储512MB
     *  <pre>
     *      set k v :设置键值对
     *      get k :通过键获取值
     *      del k :通过 k，删除键值对
     *      str.len k :求 k 指向字符串的长度
     *      get.set k v :修改原来 k 的对应值，并将旧值返回
     *      get.range k s e :获取范围s-e的子串
     *      append k v :将新的字符串 v，加入到原来 k 指向的字符串末
     *  </pre>
     **/
    STRING("string"),
    /** 基本数据类型：哈希，是string类型的field和value的映射表，适合用于存储对象，每个 hash 可以存储 2^(32-1) 键值对（40多亿）
     *  <pre>
     *      h.del k f1 f2... :删除 hash 结构中的某个（些）字段
     *      h.exists k f :判断 hash 结构中是否存在 field 字段
     *      h.get.tall k :获取所有 hash 结构中的键值
     *      h.inc.rby k f i :指定给 hash 结构中的某一字段加上一个整数
     *      h.inc.rby.float k f i :指定给 hash 结构中的某一字段加上一个浮点数
     *      h.keys k :返回 hash 中所有的键
     *      h.len k :返回 hash 中键值对的数量
     *      hm.get k f1 f2... :返回 hash 中指定的键的值，可以是多个
     *      hm.set k f1 v1 f2 v2... :hash 结构设置多个键值对
     *      h.set k f v :在 hash 结构k中设置键值对(f,v)
     *      h.set.nx k f v :当 hash 结构中不存在对应的键，才设置值
     *      h.vals k :获取 hash 结构中所有的值
     *  </pre>
     **/
    HASH("hash"),
    /** 基本数据类型：列表，简单的字符串列表,最多可存储 2^(32-1)元素 (4294967295, 每个列表可存储40多亿)。
     * <pre>
     *     l.push k n... :把节点 node1 加入到链表最左边
     *     r.push k n... :把节点 node1 加入到链表最右边
     *     l.index k i :读取下标为 index 的节点
     *     l.len k :列表长度
     *     l.pop k :删除左边第一个节点，并将其返回
     *     r.pop k :删除右边第一个节点，并将其返回
     *     l.insert k b|a p n 	:插入一个节点 n，并且可以指定在值为 p 的节点的前面（b）或者后面（a)）
     *     l.pushx l n  	:如果存在 key 为 l 的链表，则插入节点 n, 并且作为从左到右的第一个节点
     *     r.pushx l n  	:如果存在 key 为 l 的链表，则插入节点 n，并且作为从左到右的最后个节点
     *     l.range l start end :获取链表 l 从 start 下标到 end 下标的节点值
     *     l.rem l c v :如果c为 0,则删除所有值等于v的节点：如果c不是0，则先对c取绝对值,假设记为abs，然后从左到右删除不大于abs个等于v的节点
     *     l.set k i n :设置列表下标为 i 的节点的值为 n
     *     l.trim k s e 	:修剪链表，只保留下标从s到e的区间的节点，其余的都删除掉
     * </pre>
     **/
    LIST("list"),
    /** 基本数据类型：集合，string类型的无序集合,通过哈希表实现的,第二次插入存在的元素将被忽略,集合中最大的成员数为 2^(32-1)(4294967295, 每个集合可存储40多亿个成员)
     *  <pre>
     *      s.add k m1... :给键k的集合增加成员
     *      s.card k :统计k的集合成员数
     *      s.diff k1 k2 :找出两个集合的差集
     *      s.diff.store des k1 k2 :先按 s.diff 命令的规则，找出 k1 和 k2 两 个集合的差集，然后将其保存到 des 集合中
     *      s.inter k1 k2 :求k1和k2集合的交集
     *      s.inter.store des k1 k2 :先按 s.inter 命令的规则，找出 k1 和 k2 两个集合的交集，然后保存到 des 中
     *      s.is.member k m :判断m是否为k集合的成员
     *      s.members k :返回集合所有成员
     *      s.move s d m :将成员m从集合s迁移到集合d中
     *      s.pop k :随机弹出k集合的一个元素
     *      s.rand.member k c :随机返回k集合中一个或者多个元素，c 为限制返回总数，如果 c 为负数，则先求其绝对值
     *      s.rem k m1... :移除k集合中的元素m，可以是多个元素m
     *      s.union k1 k2 :求两个集合的并集
     *      s.union.store d k1 k2 :先执行 s.union 命令求出k1和k2并集，然后保存到键为 d 的集合中
     *  </pre>
     **/
    SET("set"),
    /** 基本数据类型：(sorted set)有序集合，string类型元素的集合,且不允许重复,每个元素会关联double类型的分数（排序使用）
     *  <pre>
     *      z.add k s1 v1 s2 v2 ... :向有序集合k,增加一个或多个元素v(分数s)
     *      z.card k :获取有序集合k的成员数
     *      z.count k min max :根据分数范围min-max返回集合k的元素
     *      z.inc.rby k i m ：给有序集合成员值为 m 的分数增加 i
     *      z.inter.store d n k1 k2... :求多个有序集合的交集，并且将n个结果保存到 d 中
     *      z.lex.count k min max :求有序集合 k 成员值在 min 和 max 的范围
     *      z.range k s e [score] :按照分值的大小（从小到大）返回成员，加入 s 和 e 参数可以截取某一段返回。如果输入可选项 score，则连同分数一起返回
     *      z.rank k m :按从小到大求有序集合的排行
     *      z.range.by.lex k min max [limit offset count] :根据值的大小，从小到大排序，min 为最小值，max 为最大值；limit 选项可选，当 Redis 求出范围集合后，会生产下标 0 到 n，然后根据偏移量 offset 和限定返回数 count，返回对应的成员
     *      z.range.by.score k min max [score][limit offset count] ：根据分数大小，从小到大求取范围，选项 score 和 limit 请参考 z.range 命令和 z.range.by.lex 说明
     *      z.rem.range.by.score k s e ：根据分数区间进行删除
     *      z.rem.range.by.rank k s e ：按照分数排行从小到大的排序删除，从 0 开始计算
     *      z.rem.range.by.lex k min max ：k集合按min-max值分布，进行删除
     *      z.rev.range k s e [score] :k集合从大到小范围s-e，分数排序 参考z.range
     *      z.rev.range.by.score k s e [score] :k集合从大到小范围s-e，分数排序 参考z.range.by.score
     *      z.rev.rank k m ：按从大到小的顺序，求k集合m元素的排行
     *      z.score k m :返回集合k成员m的分数值
     *      z.union.store d n k1 k2... :求多个有序集合k1、k2...的并集，其中 n 是有序集合d的个数
     *  </pre>
     **/
    Z_SET("zSet"),
    /** 扩展数据类型：基数是一种算法，评估大约需要准备多少个存储单元去存储数据，存在可控的误差(0.81%),只占用12kb
     * <pre>
     *     pf.add k e :添加指定元素到 HyperLogLog 中
     *     pf.count k :返回 HyperLogLog 的基数值
     *     pf.merge desKey k1 [k2 k3...]  	:合并多个 HyperLogLog，并将其保存在 desKey 中
     * </pre>
     **/
    HYPER_LOG_LOG("HyperLogLog"),
    /** 扩展数据类型：位图，底层是string，可以多个与，或，异或运算
     * <pre>
     *     set.bit k i 0/1 设置某位的值
     *     get.bit k i 获取某位的值
     *     bit.count k s e 获取指定范围s-e内为1的数量
     *     bit.pos k b s e 获取第一个值为bit的从start到end字符索引范围的位置
     *     bit.op and/or/xor/not destKey k1 k2 对多个 bitmap 进行逻辑运算
     * </pre>
     **/
    BIT_MAP("bitMap"),
    /** 扩展数据类型：地理围栏，
     * <pre>
     *     geo.add k longitude latitude e :(后面可配置多个三元组) 添加元素
     *     geo.dist k e1 e2 unit :计算两个元素的距离
     *     geo.pos k e [e] :获取元素的位置
     *     geo.hash k e :获取元素hash
     *     geo.radius.by.member k member radius m|km|ft|mi ASC/DESC [距离] [hash] [坐标] 获取元素附近的元素 可附加后面选项[距离][hash][坐标]
     *     geo.radius k longitude latitude radius m|km|ft|mi ASC/DESC [距离] [hash] [坐标] :和上面一样只是元素改成了指定坐标值
     * </pre>
     * */
    GEO_HASH("geoHash"),
    /** 扩展数据类型：布隆过滤器，去重、过滤、穿透，精度不高
     * <pre>
     *     bf.add k element 添加
     *     bf.exists k e 判断是否存在
     *     bf.m.add k e1 e2 ... 批量添加
     *     bf.m.exists k e1 e2 ... 批量判断
     * </pre>
     **/
    BLOOM_FILTER("bloomFilter"),
    /** key不存在*/
    NONE("none")
    ;
    private final String name;
    RedisDataEnum(String name){ this.name = name; }
    public String getName() { return name; }
    /**
     * 忽略大小写判断
     * @param type 待判断的类型
     * @return 是否一致
     */
    public boolean eq(String type){ return name.equalsIgnoreCase(type);}
}
